Conversation
|
I think I would prefer to generalize to the transition per prop format before passing to native so we always use the same format and don’t end up with duplicate props. I would also just pass array of objects at the point, will be simpler. So for the codegen I would do something like: interface TransitionConfig { interface Transitions { transitions: Transitions then in js we can normalize from the nice transition type we have to this shape. Can also provide a default value there if one wasn’t passed. in native to get transition for a prop we can do transitions.prop || transitions.default |
d48c482 to
befb0c7
Compare
8b48ee8 to
772755e
Compare
| /** Resolve the transition prop into a fully-populated NativeTransitions struct. */ | ||
| function resolveTransitions(transition?: Transition): NativeTransitions { | ||
| // Single transition: apply the same config to all 11 slots | ||
| if (transition != null && isSingleTransition(transition)) { |
There was a problem hiding this comment.
If we have a single transition I think we should just pass {{ default: config }} instead of setting the config to all props.
src/EaseView.tsx
Outdated
|
|
||
| // No transition: use library defaults per category | ||
| if (transition == null) { | ||
| const result = { defaultConfig: TIMING_DEFAULT_CONFIG } as Record< |
There was a problem hiding this comment.
Same here, we should just pass {{ default: DEFAULT_CONFIG }}
src/EaseView.tsx
Outdated
| defaultConfig: defaultNative ?? TIMING_DEFAULT_CONFIG, | ||
| } as Record<string, NativeTransitionConfig>; | ||
|
|
||
| for (const key of TRANSITION_KEYS) { |
There was a problem hiding this comment.
Also I feel like this might not be needed?
The way I see it here is just all we need to do is add the default config if one is not passed.
So if we pass:
transition={{}}we send to nativetransitions={{ default: DEFAULT_TRANSITION }}transition={{alpha: {...}}}send to nativetransitions={{ default: DEFAULT_TRANSITION, alpha: {...}}}transition={{default: { some values }}}send to nativetransitions={{default: { some values }}}
| }>; | ||
|
|
||
| type NativeTransitions = Readonly<{ | ||
| defaultConfig: NativeTransitionConfig; |
There was a problem hiding this comment.
I think we can make all the props optional / nullable here, except defaultConfig that will always be there.
| }; | ||
|
|
||
| /** Full transitions struct passed to native. */ | ||
| type NativeTransitions = { |
There was a problem hiding this comment.
Do we need this? Cant we just use the codegen type directly?
| if (props.transitionLoop == EaseViewTransitionLoop::Repeat) { | ||
| if (config.loop == "repeat") { | ||
| timing.repeatCount = HUGE_VALF; | ||
| } else if (props.transitionLoop == EaseViewTransitionLoop::Reverse) { |
There was a problem hiding this comment.
can this stay an enum in the codegen
| | NoneTransition; | ||
|
|
||
| /** Per-property transition map. Each key overrides the transition for that animatable property. */ | ||
| export type TransitionMap = { |
There was a problem hiding this comment.
I just realized it might not make sense to allow having a different config for transforms (scale, translate, roration). On iOS we set all of those together as a matrix so I dont think it is possible to animated with different timings, on Android it seems possible and on web probably not since it is all the transform prop.
What I suggest is instead of having a config for all transforms we just have a transform config that will apply to all transforms.
SO options would become
- default
- transform
- opacity
- borderRadius
- backgroundColor
Summary
EaseView, allowing different animation configs per animatable property (e.g., spring foropacity, timing fortranslateX,noneforscale)TransitionMaptype withdefaultfallback and per-propertySingleTransitionoverridestype: 'none'to immediately snap a property to its target value without animationAPI Example
Solution
src/types.ts— newSingleTransition,TransitionMap, and updatedTransitionunion typesrc/EaseView.tsx— resolve per-property transition maps into flat native props (transitionOpacityType,transitionOpacityDuration, etc.)src/EaseViewNativeComponent.ts— codegen props for per-property transition overridesios/EaseView.mm— resolve per-property transition config on the native side, supportnonetype for immediate value applicationandroid/EaseView.kt+EaseViewManager.kt— per-property transition resolution andnonesupportsrc/__tests__/EaseView.test.tsx— tests for per-property resolution,defaultfallback, andnonebehaviorexample/src/App.tsx— demo showcasing per-property transitionsREADME.md— documentation for the new APITest Plan
Per-Property Transitions demo — opacity fades slowly (1.5s easeInOut) while translateX bounces with a spring. The timing difference between properties is clearly visible.
iOS — iPhone 17 Pro (iOS 26.2)
pr4-ios-trimmed.mp4
Android — Android 16 emulator (arm64)
pr4-android-trimmed.mp4
Web — Chrome, 390px viewport
pr4-web-final.mp4